import { _decorator, Component, Node, RigidBody, Vec3, v3, Light, SpotLight, math, Camera, AudioSource, AudioClip } from 'cc';
import { Constant } from '../Common/Constant';
import { ZTool } from '../Common/ZTool';
import { GameManager } from '../Manager/GameManager';
import { CameraController } from './CameraController';
import { EasyController, EasyControllerEvent } from './EasyController';
import { SpotLightController } from './SpotLightController';
const { ccclass, property } = _decorator;

const v3_1 = v3();
const v3_2 = v3();

const ROTATION_STRENGTH = 20.0;

@ccclass('PlayerController')
export class PlayerController extends Component {

    static isTremble: boolean = false;

    @property(SpotLightController)
    spotLightCtrl: SpotLightController = null!;

    @property(AudioClip)
    footClip: AudioClip = null!;

    @property(AudioClip)
    runClip: AudioClip = null!;

    rigidbody: RigidBody = null!;
    audio: AudioSource = null!;

    camera: CameraController = null!;

    moveForce: Vec3 = new Vec3(0, 0, 0);
    dir: Vec3 = v3();

    speed: number = 2;
    _velocityScale: number = 1.0;

    private _isRun: boolean = false;
    private _isMoving: boolean = false;

    onLoad() {
        this.rigidbody = this.node.getComponent(RigidBody);
        this.audio = this.node.getComponent(AudioSource);
        this.camera = this.node.getChildByName("Main Camera").getComponent(CameraController);
    }

    start() {
        this.node.hasChangedFlags = 1;

        EasyController.on(EasyControllerEvent.CAMERA_ROTATE, this.OnRotate, this);
        EasyController.on(EasyControllerEvent.MOVEMENT, this.OnMove, this);
        EasyController.on(EasyControllerEvent.MOVEMENT_STOP, this.OnStopMove, this);
        //EasyController.on(EasyControllerEvent.JUMP, this.onJump, this);

        this.targetAngles.set(this.node.eulerAngles);
    }

    IsRun(isRun: boolean) {
        this.speed = isRun ? 5 : 2;
        this._isRun = isRun;
    }

    private _tmp = v3();
    OnMove(x: number, y: number, offset: number) {
        this._velocityScale = 1;

        let dir = v3(x, 0, -y).normalize();

        let radian = Vec3.angle(Vec3.FORWARD, this.camera.node.forward);//Vec3.FORWARD（0，0，-1）

        if (this.camera.node.eulerAngles.y < 0) {
            radian = this.camera.node.eulerAngles.y % 360 >= -180 ? -radian : radian;
        }

        if (this.camera.node.eulerAngles.y > 0) {
            radian = this.camera.node.eulerAngles.y % 360 >= 180 ? -radian : radian;
        }

        Vec3.rotateY(this._tmp, dir, Vec3.ZERO, radian);

        this._tmp.multiplyScalar(this.speed);

        this._isMoving = true;

        this.PlayAudio(this._isRun ? this.runClip : this.footClip);

        this.VP -= Constant.VPGap;
    }

    OnStopMove() {
        this._isMoving = false;
        if (this.rigidbody) {
            this.rigidbody.setLinearVelocity(Vec3.ZERO);
        }

        this.audio.stop();
    }

    PlayAudio(clip: AudioClip) {
        if ((this._isRun && this.audio.clip == this.runClip) && this.audio.playing) return;
        if ((!this._isRun && this.audio.clip == this.footClip) && this.audio.playing) return;

        this.audio.clip = clip;
        this.audio.play();
    }

    targetAngles: Vec3 = v3();
    rotateVHSeparately: boolean = false;
    tweenTime: number = 0.2;

    OnRotate(deltaX: number, deltaY: number) {
        let eulerAngles = this.camera.node.eulerAngles;
        if (this.rotateVHSeparately) {
            if (Math.abs(deltaX) > Math.abs(deltaY)) {
                deltaY = 0;
            }
            else {
                deltaX = 0;
            }
        }

        this.camera.SetTargetAngle(math.clamp(eulerAngles.x + deltaX * ROTATION_STRENGTH, -80, 80)
            , eulerAngles.y + deltaY * ROTATION_STRENGTH, eulerAngles.z);
    }

    update(deltaTime: number) {
        if (this._isMoving) {
            this._tmp.multiplyScalar(this._velocityScale);
            if (this.rigidbody) {
                this.rigidbody.getLinearVelocity(v3_1);
                this._tmp.y = v3_1.y;
                this.rigidbody.setLinearVelocity(this._tmp);
            }
            else {
                this._tmp.multiplyScalar(deltaTime);
                this._tmp.add(this.node.position);
                this.node.setPosition(this._tmp);
            }
        }
    }

    onDestroy() {
        EasyController.off(EasyControllerEvent.MOVEMENT, this.OnMove, this);
        EasyController.off(EasyControllerEvent.MOVEMENT_STOP, this.OnStopMove, this);
        //EasyController.off(EasyControllerEvent.MOVEMENT_STOP, this.onJump, this);
        EasyController.off(EasyControllerEvent.CAMERA_ROTATE, this.OnRotate, this);
    }

    private hp: number = 100;   //血量
    private vp: number = 100;   //体力
    private bv: number = 60;    //电量
    private atk: number = 100;  //攻击
    private ac: number = 0;     //护甲

    public get HP() {
        return this.hp;
    }

    public set HP(value: number) {
        this.hp += value;

        if (this.hp <= 0) {
            this.hp = 0;
            //TODO 生命值为零
        }
    }

    public get VP() {
        if (this.vp < 0) this.vp = 0;
        return this.vp;
    }

    public set VP(value: number) {
        this.vp = value;

        if (this.vp <= 0) {
            this.vp = 0;
            //TODO 体力值为零
        }

        console.log(this.VP);

        GameManager.Instance.scene.emit(EasyControllerEvent.BATTERY_CHANGED, this.VP);
    }

    public get BV() {
        return this.bv;
    }

    public set BV(value: number) {
        this.bv += value;

        if (this.bv <= 0) {
            this.bv = 0;
            //TODO 电量为零
        }
    }

}